package com.online.fund.spider;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.annotation.Resource;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.online.fund.spider.dao.FundDao;
import com.online.fund.spider.entity.SharesTransaction;
import com.online.fund.util.HttpClientUtil;

/**
 * 股票所有的交易数据
 * 
 * @author galen.zhang
 *
 */
@Service
public class SharesAllTransactionProcesser {

	private final static Logger logger = LoggerFactory.getLogger(SharesAllTransactionProcesser.class);

	private ExecutorService pool = Executors.newFixedThreadPool(20);

	@Resource
	private FundDao fundDao;

	private final static String SHARES_TRANSACTION_PAGE_URL_SH = "http://quote.eastmoney.com/sh#{sharesCode}.html";
	private final static String SHARES_TRANSACTION_PAGE_URL_SZ = "http://quote.eastmoney.com/sz#{sharesCode}.html";
	private final static String TRANSACTION_DATA_URL = "http://pdfm2.eastmoney.com/EM_UBG_PDTI_Fast/api/js?id=#{refId}&TYPE=k&rtntype=5&isCR=false&authorityType=fa&fsData1516916235760=fsData1516916235760";

	private static Map<String, String> SHARES_TYPE_MAP = new HashMap<String, String>();

	static {
		SHARES_TYPE_MAP.put("C.2", "上证A股");
		SHARES_TYPE_MAP.put("C.3", "上证B股");
		SHARES_TYPE_MAP.put("C._SZAME", "深证A股");
		SHARES_TYPE_MAP.put("C.7", "深证B股");
	}

	public void parsePage() {
		try {
			List<SharesTransaction> sharesTransactionList = null;
			
			// 上证A股
//			sharesTransactionList = fundDao.querySharesTransactionByTypeCode("C.2");
//			System.out.println(sharesTransactionList.size());
//			parsePage(sharesTransactionList, "C.2", true);

			// 上证B股
//			sharesTransactionList = fundDao.querySharesTransactionByTypeCode("C.3");
//			System.out.println(sharesTransactionList.size());
//			parsePage(sharesTransactionList, "C.3", true);

//			// 深证A股
			sharesTransactionList = fundDao.querySharesTransactionByTypeCode("C._SZAME");
			System.out.println(sharesTransactionList.size());
			parsePage(sharesTransactionList, "C._SZAME", true);

//			// 深证B股
//			sharesTransactionList = fundDao.querySharesTransactionByTypeCode("C.7");
//			System.out.println(sharesTransactionList.size());
//			parsePage(sharesTransactionList, "C.7", true);

			pool.shutdown();
			while (!pool.isTerminated()) {
				Thread.sleep(1000);
			}
			HttpClientUtil.closeConnectionPool();
		} catch (Exception e) {
			logger.error(e.getMessage());
		}
	}

	@SuppressWarnings("unchecked")
	public void parsePage(List<SharesTransaction> sharesTransactionList, String sharesTypeCode, boolean saveFlag) {

		try {
			if (saveFlag) {
				fundDao.deleteSharesTransaction(null, sharesTypeCode);
			}
			for (SharesTransaction sharesTransaction : sharesTransactionList) {
				System.out.println(sharesTransaction.getSharesCode());
				String pageHtml = null;
				if ("C.2".equals(sharesTypeCode) || "C.3".equals(sharesTypeCode)) {
					pageHtml = HttpClientUtil.httpGetRequest(SHARES_TRANSACTION_PAGE_URL_SH.replace("#{sharesCode}", sharesTransaction.getSharesCode()));
				} else {
					pageHtml = HttpClientUtil.httpGetRequest(SHARES_TRANSACTION_PAGE_URL_SZ.replace("#{sharesCode}", sharesTransaction.getSharesCode()));
				}

//				System.out.println(pageHtml);
	
				Document doc = Jsoup.parse(pageHtml);
				String stockId = null;
				if (doc.select("meta[name='mobile-agent']").hasAttr("content")) {
					String content = doc.select("meta[name='mobile-agent']").eachAttr("content").get(0);
					stockId = content.substring(content.lastIndexOf("/") + 1, content.length() - 5);
				} else {
					String imgSrc = doc.select("#picr img").get(0).attr("src");
					int index = imgSrc.indexOf("id=");
					if (index > 0) {
						//System.out.println(imgSrc.substring(index+3, imgSrc.indexOf("&")));
						stockId = imgSrc.substring(index+3, imgSrc.indexOf("&"));
					}
//					System.out.println(imgSrc);
				}
				
				if (stockId != null) {
					sharesTransaction.setRefId(stockId);
					pool.execute(() -> {
						try {
							String jsStr = HttpClientUtil.httpGetRequest(
									TRANSACTION_DATA_URL.replace("#{refId}", sharesTransaction.getRefId()));
							if (jsStr != null && jsStr.length() > 2) {
								jsStr = jsStr.substring(1, jsStr.length() - 1);

								JSONObject obj = JSON.parseObject(jsStr);
								List<String> strList = (List<String>) obj.get("data");
								if (strList.size() > 365) {
									strList = strList.subList(strList.size() - 365, strList.size());
								}

								List<SharesTransaction> transactionList = new ArrayList<SharesTransaction>();
								for (String dataStr : strList) {
									String[] dataArr = dataStr.split(",");
									SharesTransaction transaction = new SharesTransaction();
									transaction.setSharesCode(sharesTransaction.getSharesCode());
									transaction.setSharesName(sharesTransaction.getSharesName());
									transaction.setSharesTypeCode(sharesTransaction.getSharesTypeCode());
									transaction.setSharesTypeName(sharesTransaction.getSharesTypeName());

									transaction.setCrawlDate(dataArr[0]);
									// 今开
									if (!dataArr[1].contains("-")) {
										transaction.setTodayOpenPrice(Double.parseDouble(dataArr[1]));	
									}

									// 最新
									if (!dataArr[2].contains("-")) {
										transaction.setLatestPrice(Double.parseDouble(dataArr[2]));
									}
									
									// 最高
									if (!dataArr[3].contains("-")) {
										transaction.setMaxPrice(Double.parseDouble(dataArr[3]));
									}
									
									// 最低
									if (!dataArr[4].contains("-")) {
										transaction.setMinPrice(Double.parseDouble(dataArr[4]));
									}
									
									// 成交量
									if (!dataArr[5].contains("-")) {
										transaction.setTradingVolume(Double.parseDouble(dataArr[5]));
									}

									// 成交额
									if (!dataArr[6].contains("-")) {
										if (dataArr[6].contains("万")) {
											transaction.setTradingVolumeAmount(Double.parseDouble(dataArr[6].replace("万", "")) * 10000); 
										} else if (dataArr[6].contains("亿")) {
											transaction.setTradingVolumeAmount(Double.parseDouble(dataArr[6].replace("亿", "")) * 100000000); 
										} else {
											transaction.setTradingVolumeAmount(Double.parseDouble(dataArr[6]));
										}
									}
									
									// 振幅
									if (!dataArr[7].contains("-")) {
										transaction.setAmplitude(Double.parseDouble(dataArr[7].replace("%", "")));
									}
//									System.out.println(dataArr[0]);
									
									transactionList.add(transaction);
								}
								
								if (saveFlag && !transactionList.isEmpty()) {
									fundDao.batchAddSharesTransaction(transactionList);
									transactionList.clear();
								} else {
									System.out.println(strList.size());
									System.out.println(transactionList);
								}
							}
						} catch (IOException e) {
							logger.error(e.getMessage());
						}
					});
				}

			}

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public static void main(String[] args) throws Exception {
		SharesAllTransactionProcesser processer = new SharesAllTransactionProcesser();
		SharesTransaction sharesTransaction = new SharesTransaction();
		sharesTransaction.setSharesCode("900902");
		List<SharesTransaction> sharesTransactionList = new ArrayList<SharesTransaction>();
		sharesTransactionList.add(sharesTransaction);
		processer.parsePage(sharesTransactionList, "C.3", false);

		processer.pool.shutdown();
		while (!processer.pool.isTerminated()) {
			Thread.sleep(1000);
		}
		HttpClientUtil.closeConnectionPool();
	}
}
